/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.generator.entityGenerator;

import com.inspur.edp.caf.generator.BaseGenerator;
import com.inspur.edp.caf.generator.compileunit.CompileUnitGenerator;
import com.inspur.edp.caf.generator.compileunit.CompileUnitGeneratorContext;
import com.inspur.edp.cef.gencommon.MediateType;
import com.inspur.edp.cef.generator.entityGenerator.base.DataTypeGenerator;
import com.inspur.edp.cef.generator.entityGenerator.base.confignames.ConfigNamesGenerator;
import com.inspur.edp.cef.generator.overall.CefGeneratorContext;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;

public abstract class BaseEntityGenerator extends CompileUnitGenerator {
  private CefGeneratorContext cefGenContext;

  protected BaseEntityGenerator(CefGeneratorContext cefGenContext) {
    super();
    this.cefGenContext = cefGenContext;
    cefGenContext.setEntityGenerator(this);
  }

  protected CefGeneratorContext getCefGenContext() {
    return cefGenContext;
  }

  @Override
  public BaseEntityGeneratorContext getContext() {
    return (BaseEntityGeneratorContext) super.getContext();
  }

  @Override
  protected java.util.ArrayList<BaseGenerator> createChildGenerators() {
    //		ArrayList<BaseGenerator> children = new ArrayList<BaseGenerator>();
    //		children.add(getDataTypeGenerator());
    ArrayList<BaseGenerator> generators = new ArrayList<BaseGenerator>(
        Arrays.asList(new BaseGenerator[] {getDataTypeGenerator()}));
    if(getHasConfig()){
      generators.add(getConfigNamesGenerator());
    }
    return generators;
  }

  protected ConfigNamesGenerator getConfigNamesGenerator() {
    return null;
  }

  protected boolean getHasConfig() {
    return false;
  }

  protected abstract DataTypeGenerator getDataTypeGenerator();

  @Override
  protected final CompileUnitGeneratorContext createProjectInfoContext() {
    cefGenContext.setEntityGenContext(createDataTypeGenContext());
    return cefGenContext.getEntityGenContext();
  }

  protected abstract BaseEntityGeneratorContext createDataTypeGenContext();

  @Override
  protected String getFilePath() {

    return cefGenContext.getMetadataJitContext().getCodePath();
  }

  public final void setCefContextEntityTypes() throws ClassNotFoundException {
    getContext().getCefGenContext().setRootDataInterfaceType(getContext().getRootNodeType());
    // if (!string.IsNullOrEmpty(Context.ChangeSerializerType.ClassName))
    //    Context.CefGenContext.ChangeSerializerType =
    // cefGenContext.ProjectApiAssembly.GetType(Context.ChangeSerializerType.getFullName());
    getContext().getCefGenContext().setRootNodeCode(getContext().getRootNodeCode());
    setDataInterfaceTypes();
    setNodeConstsTypes();
    setAssociationClassTypes();
    setEnumClassTypes();
    baseEntityAfterGenerate();
  }

  private void setDataInterfaceTypes() throws ClassNotFoundException {
    for (Map.Entry<String, MediateType> item : getContext().getNodeTypes().entrySet()) {
      getContext().getCefGenContext().getDataInterfaceTypes().put(item.getKey(), item.getValue());
    }
  }

  private void setNodeConstsTypes() throws ClassNotFoundException {
    for (Map.Entry<String, MediateType> item : getContext().getNodeConsts().entrySet()) {
      getContext().getCefGenContext().getNodeConstTypes().put(item.getKey(), item.getValue());
    }
  }

  private void setAssociationClassTypes() throws ClassNotFoundException {
    for (Map.Entry<String, MediateType> item :
        getContext().getElementAssociationTypes().entrySet()) {
      cefGenContext.getElementAssociationTypes().put(item.getKey(), item.getValue());
    }
  }

  private void setEnumClassTypes() throws ClassNotFoundException {
    for (Map.Entry<String, MediateType> item : getContext().getElementEnumTypes().entrySet()) {
      cefGenContext.getElementEnumTypes().put(item.getKey(), item.getValue());
    }
  }

  protected void baseEntityAfterGenerate() {}

  @Override
  protected void beforeInitialize() {
    super.beforeInitialize();
    getContext().setDefaultPackageName(getPackageName());
  }
}
